/*
  GRANITE DATA SERVICES
  Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.

  This file is part of Granite Data Services.

  Granite Data Services is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation; either version 3 of the License, or (at your
  option) any later version.

  Granite Data Services is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
  for more details.

  You should have received a copy of the GNU Lesser General Public License
  along with this library; if not, see <http://www.gnu.org/licenses/>.
*/

package pl.pawluk.inz.services;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.granite.messaging.service.annotations.RemoteDestination;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import pl.pawluk.inz.dao.AuthoritiesMapper;
import pl.pawluk.inz.dao.IFilesDao;
import pl.pawluk.inz.dao.UsersMapper;
import pl.pawluk.inz.dto.UserDTO;
import pl.pawluk.inz.entities.*;
import pl.pawluk.inz.exceptions.ErrorCodes;
import pl.pawluk.inz.exceptions.VLPException;

import java.util.*;


@Service
@RemoteDestination(id = "welcomeService", source = "welcomeService")
public class WelcomeServiceImpl implements WelcomeService {
    private static final Log log = LogFactory.getLog(WelcomeServiceImpl.class);

    @Autowired
    private IFilesDao filesDao;
    @Autowired
    private ConversionService conversionService;
    @Autowired
    private AuthoritiesMapper authoritiesMapper;

    @Autowired
    private UsersMapper usersMapper;


    @Override
    @Secured("ROLE_USER")
    public String getFileName() {
        return filesDao.findById(1l).getName();
    }

    @Override
    @Transactional
    public UserDTO getUserInfo(String email) {
        UsersCriteria uc = new UsersCriteria();
        uc.createCriteria().andEmailEqualTo(email);
        Users u = DataAccessUtils.uniqueResult(usersMapper.selectByExample(uc));
//        log.info("PP1: " + u.getGroups().size());
        UserDTO dto = conversionService.convert(u, UserDTO.class);
        return dto;
    }

    @Override
    @Secured("ROLE_USER")
    @Transactional(readOnly = true)
    public List<UserDTO> getAllUsers() {
        List<Users> qRes = usersMapper.selectByExample(new UsersCriteria());
        if (qRes == null) {
            return null;
        }
        List<UserDTO> users = new ArrayList<UserDTO>(qRes.size());
        for (Iterator<Users> iter = qRes.iterator(); iter.hasNext(); ) {
            Users u = iter.next();
            UserDTO cUser = conversionService.convert(u, UserDTO.class);
            AuthoritiesCriteria c = new AuthoritiesCriteria();
            c.createCriteria().andUserIdEqualTo(u.getId());
            List<AuthoritiesKey> authoritiesKeys = authoritiesMapper.selectByExample(c);
            if (authoritiesKeys != null) {
                for (final AuthoritiesKey k : authoritiesKeys) {
                    cUser.getAuthorities().add(k.getAuthority());
                }
            }
            users.add(cUser);
        }
        return users;
    }

    @Override
    @Secured("ROLE_USER")
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public void updateUser(UserDTO user) {
        throw new VLPException(ErrorCodes.BLAD_LOGOWANIA, user.getEmail());
//        Users uEnt = conversionService.convert(user, Users.class);
//        uEnt.setPassword(EncryptionUtils.encode(uEnt.getPassword()));
//        usersMapper.updateByPrimaryKey(uEnt);
//        for (Iterator<String> aIter = user.getAuthorities().iterator(); aIter.hasNext(); ) {
//            AuthoritiesKey e = new AuthoritiesKey();
//            e.setAuthority(aIter.next());
//            e.setUserId(uEnt.getId());
//            authoritiesMapper.deleteByPrimaryKey(e);
//            authoritiesMapper.insert(e);
//        }
    }

    @Override
    @Secured("ROLE_USER")
    public void deleteUser(UserDTO user) {
        Users uEnt = conversionService.convert(user, Users.class);
        usersMapper.deleteByPrimaryKey(user.getId());
    }

    @Override
    public void createUser(UserDTO user) {
        Users uEnt = conversionService.convert(user, Users.class);
        usersMapper.insertSelective(uEnt);
    }
}
